/*
 * The StringWriter class is a helper tool designed to write assembler statements 
 * to expedite the construction of strings in assembler programs.
 * 
 * The String Writer operates under the assumption that strings are written to 
 * the heap and a pointer to the string is created on the stack.  This configuration
 * allows the persistent string data to be maintained in the heap space while the 
 * pointer to the persistent data segment can be passed throughout the program
 * space.
 * 
 * Strings in the system are also null terminated to minimize the number of parameters
 * required for string operations. 
 * */

package tools;

public class StringWriter {
	
	static Integer heapOffset;
	static Integer lineAddress;
	
	public static void main( String[] args ) {
		/*
		int startAddress = 1048;
		String toWrite = "ENTER A VALUE(0-32767):";
		int stackOffsetOfStringPointer = 8;
		int promptIndex = 1;
		int stackOffsetOfCharacterZero = 0;
		int stackOffsetOfCharacterA = 6;
		*/
		/*
		int startAddress = 1292;
		String toWrite = "THE VALUES ENTERED:";
		int stackOffsetOfStringPointer = 10;
		int promptIndex = 2;
		int stackOffsetOfCharacterZero = 0;
		int stackOffsetOfCharacterA = 6;
		*/
		/*
		int startAddress = 1498;
		String toWrite = "CLOSEST VALUE:";
		int stackOffsetOfStringPointer = 12;
		int promptIndex = 3;
		int stackOffsetOfCharacterZero = 0;
		int stackOffsetOfCharacterA = 6;
		*/
		/*
		int startAddress = 1654;
		String toWrite = "*OVERFLOW - RETRY*\n";
		int stackOffsetOfStringPointer = 14;
		int promptIndex = 4;
		int stackOffsetOfCharacterZero = 0;
		int stackOffsetOfCharacterA = 6;
		*/
		/*
		int startAddress = 1862;
		String toWrite = "*NULL ENTERED - RETRY*\n";
		int stackOffsetOfStringPointer = 16;
		int promptIndex = 5;
		int stackOffsetOfCharacterZero = 0;
		int stackOffsetOfCharacterA = 6;
		*/
		/*
		int startAddress = 3098;
		String toWrite = "ENTER A WORD(MAX 32 CHARS):";
		int stackOffsetOfStringPointer = 8;
		int promptIndex = 1;
		int stackOffsetOfCharacterZero = 0;
		int stackOffsetOfCharacterA = 6;
		*/

		/*
		int startAddress = 3380;
		String toWrite = "WORDS ENTERED:\n";
		int stackOffsetOfStringPointer = 10;
		int promptIndex = 2;
		int stackOffsetOfCharacterZero = 0;
		int stackOffsetOfCharacterA = 6;
		*/

		/*
		int startAddress = 3548;
		String toWrite = "SORTED WORDS:\n";
		int stackOffsetOfStringPointer = 12;
		int promptIndex = 3;
		int stackOffsetOfCharacterZero = 0;
		int stackOffsetOfCharacterA = 6;
		*/

		/*
		int startAddress = 3706;
		String toWrite = "WORDS CONTAINING THE SUBWORD:\n";
		int stackOffsetOfStringPointer = 14;
		int promptIndex = 4;
		int stackOffsetOfCharacterZero = 0;
		int stackOffsetOfCharacterA = 6;
		*/

		/*
		int startAddress = 4022;
		String toWrite = "*EMPTY STRING ENTERED - RETRY*\n";
		int stackOffsetOfStringPointer = 16;
		int promptIndex = 5;
		int stackOffsetOfCharacterZero = 0;
		int stackOffsetOfCharacterA = 6;
		*/

		/*
		int startAddress = 4350;
		String toWrite = "*MAX LENGTH EXCEEDED - RETRY*\n";
		int stackOffsetOfStringPointer = 18;
		int promptIndex = 6;
		int stackOffsetOfCharacterZero = 0;
		int stackOffsetOfCharacterA = 6;
		*/

		/*
		int startAddress = 6452;
		String toWrite = "VECTOR1:";
		int stackOffsetOfStringPointer = 10;
		int promptIndex = 1;
		int stackOffsetOfCharacterZero = 0;
		int stackOffsetOfCharacterA = 8;
		*/

		/*
		int startAddress = 6550;
		String toWrite = "VECTOR2:";
		int stackOffsetOfStringPointer = 12;
		int promptIndex = 2;
		int stackOffsetOfCharacterZero = 0;
		int stackOffsetOfCharacterA = 8;
		*/

		///*
		int startAddress = 6648;
		String toWrite = "RESULT:";
		int stackOffsetOfStringPointer = 14;
		int promptIndex = 3;
		int stackOffsetOfCharacterZero = 0;
		int stackOffsetOfCharacterA = 8;
		//*/
				
		heapOffset = 0;
		
		char[] charsToWrite = toWrite.toCharArray();
		lineAddress = startAddress;
		
		for( int i = 0; i < charsToWrite.length; i++ ) {
			char currentChar = charsToWrite[i];
			
			writeCharacterInstructions(stackOffsetOfCharacterZero, stackOffsetOfCharacterA, currentChar  );
			
		}
		writeCharacterInstructions(stackOffsetOfCharacterZero, stackOffsetOfCharacterA, (char)0 );
		
		String line = "";

		line = Integer.toString( lineAddress );
		line += ":LDA,0,true,false,10\t\t;Load R0 with p(THEAP)\t\t-> R0 = p(THEAP)";
		System.out.println( line );
		lineAddress = lineAddress + 2;

		line = Integer.toString( lineAddress );
		line += ":LDA,1,true,false,10\t\t;Load R1 with p(THEAP)\t\t-> R1 = p(THEAP)";
		System.out.println( line );
		lineAddress = lineAddress + 2;

		line = Integer.toString( lineAddress );
		line += ":IAR,1," + heapOffset;
		line += "\t\t\t\t;Add " + heapOffset + "  to R1\t\t\t\t-> R1 = p(THEAP) + " + heapOffset;
		System.out.println( line );
		lineAddress = lineAddress + 2;

		line = Integer.toString( lineAddress );
		line += ":STR,1,false,false,10\t\t;Store R1 at p(THEAP)\t\t-> p(THEAP) = p(THEAP) + " + heapOffset;
		System.out.println( line );
		lineAddress = lineAddress + 2;

		line = Integer.toString( lineAddress );
		line += ":STR,0,false,true," + stackOffsetOfStringPointer + "\t\t;Store R0 at Stack(" + (stackOffsetOfStringPointer / 2) + ")\t\t-> Stack(" + (stackOffsetOfStringPointer / 2) + ") = p(Prompt" + promptIndex + ")";
		System.out.println( line );
		lineAddress = lineAddress + 2;
	}
	
	static void writeCharacterInstructions( int stackOffsetOfCharacterZero, int stackOffsetOfCharacterA, char currentChar ) {
		String line = "";
		
		line = Integer.toString( lineAddress );
		line += ":LDR,0,false,true,";
		if( currentChar <= 63 ) {
			line += stackOffsetOfCharacterZero;
			line += "\t\t;Load R0 with Stack(";
			line += (stackOffsetOfCharacterZero/2);
			line += ")\t\t-> R0 = 0 = ASCII(NULL)" ;
			System.out.println( line );
		} else if( currentChar >= 65 && currentChar <= 91 ) {
			line += stackOffsetOfCharacterA;
			line += "\t\t;Load R0 with Stack(";
			line += (stackOffsetOfCharacterA/2);
			line += ")\t\t-> R0 = 65 = ASCII(A)" ;
			System.out.println( line );
		}
		lineAddress = lineAddress + 2;
		
		int offset = 0;
		if( currentChar <= 63 ) {
			 offset = currentChar;
		} else if( currentChar >= 65 && currentChar <= 91 ) {
			offset = currentChar - 65;
		}
		
		if( offset != 0) {
			line = Integer.toString( lineAddress );
			line += ":IAR,0,";
			line += offset;
			line += "\t\t\t\t;Add " + offset + " to R0";
			if( currentChar == 0 )
				line += "\t\t\t\t-> R0 = ASCII(NULL) = ASCII(NULL) + ACSCII(" + offset + ")" ;
			if( currentChar == 10 )
				line += "\t\t\t\t-> R0 = ASCII(LF) = ASCII(LF) + ACSCII(" + offset + ")" ;
			else
				line += "\t\t\t\t-> R0 = ASCII(" + currentChar + ") = ASCII(NULL) + ACSCII(" + offset + ")" ;
			
			System.out.println( line );
			lineAddress = lineAddress + 2;
		}
		
		line = Integer.toString( lineAddress );
		line += ":LDX,false,false,10\t\t;Load X0 with p(THEAP)\t\t-> X0 = THEAP";
		System.out.println( line );
		lineAddress = lineAddress + 2;
	
		line = Integer.toString( lineAddress );
		if( currentChar == 0 )
			line += ":STR,0,false,true," + heapOffset + "\t\t;Store R0 at THeap(" + heapOffset/2 + ")\t\t-> THeap(" + heapOffset/2 + ") = R0 = ASCII(NULL)";
		else if( currentChar == 10 )
			line += ":STR,0,false,true," + heapOffset + "\t\t;Store R0 at THeap(" + heapOffset/2 + ")\t\t-> THeap(" + heapOffset/2 + ") = R0 = ASCII(LF)";
		else
			line += ":STR,0,false,true," + heapOffset + "\t\t;Store R0 at THeap(" + heapOffset/2 + ")\t\t-> THeap(" + heapOffset/2 + ") = R0 = ASCII(" + currentChar + ")";
		
			
		System.out.println( line );
		lineAddress = lineAddress + 2;
		heapOffset = heapOffset + 2;
	
		line = Integer.toString( lineAddress );
		line += ":LDX,false,false,4\t\t;Load X0 with p(TOS)\t\t-> X0 = TOS";
		System.out.println( line );
		lineAddress = lineAddress + 2;
	}
}
